﻿#include <Sys\RenderUnit\SysRenderDatagram\MUTITEXTURERD.HPP>
#include <Render\Render_Win32\Render_Win32_D3D\RENDER_WIN32_D3D9.HPP>
#include <Sys\RenderUnit\SYSDDCLASSID.HPP>
#include <Sys\RenderUnit\SysDatagramDisposal_D3D\POSTDRAWDDD3D9.HPP>
#include <Sys\RenderUnit\SysDatagramDisposal_D3D\STAGEDDD3D9.HPP>
#include <d3dx9.h>

using namespace CxxlMan;
using namespace Cxxl3D;

// extern DWORD g_TextureLevel = 0; 
//unsigned long g_ITextureRD_AttrBox_Num = 0;


class CMutiTextureDD_D3D9:public IDatagramDisposal_D3d9, public IPostDrawNotice, public IMutiTextureBridge
{

  Smart_Ptr<IStageDDD3D9> m_IStageDDD3D9_Ptr;
  Smart_Ptr<IPostDrawDDD3D9> m_IPostDrawDDD3D9_Ptr;
  unsigned long ITextureRD_AttrBox_Num;
/*
  void cxxlFASTCALL doBlendMode(unsigned char BlendMode, LPDIRECT3DDEVICE9 pDEVICE9, DWORD Stage)
  {
    switch(BlendMode)
    {
    case 1:      
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
      break;
    case 2:      
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLORARG2, D3DTA_CURRENT);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);      
      break;
    default:
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLOROP, D3DTOP_MODULATE); 
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLORARG1, D3DTA_TEXTURE);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_COLORARG2, D3DTA_CURRENT);
      pDEVICE9->SetTextureStageState(Stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    };
  }
*/

  // IPostDrawDDD3D9 經此函數通知
  virtual void cxxlFASTCALL Notice(LPDIRECT3DDEVICE9 pDEVICE9)
  {
    MutiTextureDD_D3D9_Clear(pDEVICE9);
    m_IPostDrawDDD3D9_Ptr->Del(this);
  }

  // 清除 MutiTexture 恢復內定值，主要供 CTriagleDDD3D.cpp 取用
  void cxxlFASTCALL MutiTextureDD_D3D9_Clear(LPDIRECT3DDEVICE9 pDEVICE9)
  {
    if(ITextureRD_AttrBox_Num == 0)
      return;

    pDEVICE9->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); // 讓 Texture Matrix 失效

    // 恢復 D3D 的預設
    pDEVICE9->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 
    pDEVICE9->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
    pDEVICE9->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
    pDEVICE9->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
    pDEVICE9->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);

    for(int n = 1; n < ITextureRD_AttrBox_Num; ++n)
    {
      pDEVICE9->SetTextureStageState(n, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); // 讓 Texture Matrix 失效

		  pDEVICE9->SetTextureStageState(n, D3DTSS_COLOROP, D3DTOP_DISABLE);
      pDEVICE9->SetTextureStageState(n, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
      pDEVICE9->SetTexture(n, NULL); // 關閉 Stage
    }

    ITextureRD_AttrBox_Num = 0;
  }

  virtual bool cxxlFASTCALL Exec(const Smart_Ptr<IRenderDatagramDisposalCenterD3d> &IRenderDatagramDisposalCenterD3d_Arg,
    const Smart_Ptr<IRenderDatagram> &IRenderDatagram_Arg, LPDIRECT3DDEVICE9 pDEVICE9)
  {
    // 第一次被叫用才會取得
    if(m_IStageDDD3D9_Ptr.isNULL())
      m_IStageDDD3D9_Ptr = Smart_Cast<IStageDDD3D9>(IRenderDatagramDisposalCenterD3d_Arg->GetIDatagramDisposal_D3d9(IStageD3D9_ClassID));

    // 第一次被叫用才會取得
    if(m_IPostDrawDDD3D9_Ptr.isNULL())
      m_IPostDrawDDD3D9_Ptr = Smart_Cast<IPostDrawDDD3D9>(IRenderDatagramDisposalCenterD3d_Arg->GetIDatagramDisposal_D3d9(IPostDrawDDD3D9_ClassID));

    m_IPostDrawDDD3D9_Ptr->Add(this);

    Smart_Ptr<IMutiTextureRD> IMutiTextureRD_Ptr = (IMutiTextureRD*)GetDefaultInterface(IRenderDatagram_Arg);
    Smart_Ptr<cxxlList<ITextureRD_AttrBox> > ITextureRD_AttrBox_List = GetTextureRDList(IMutiTextureRD_Ptr);

    ITextureRD_AttrBox_Num = ITextureRD_AttrBox_List->GetCount();
    if(ITextureRD_AttrBox_Num == 0)
      return true;

    ITextureRD_AttrBox_List->ResetPT(toHead);
    for(DWORD TextureLevel = 0; TextureLevel < ITextureRD_AttrBox_Num; ++TextureLevel)
    {
      m_IStageDDD3D9_Ptr->SetStage(TextureLevel); // 記錄現處 Stage

      Smart_Ptr<ITextureRD> ITextureRD_Ptr(NULL);
      Smart_Ptr<ITextureRD_AttrBox> ITextureRD_AttrBox_Ptr = (*ITextureRD_AttrBox_List)++;
      ITextureRD_AttrBox_Ptr->Get(ITextureRD_Ptr);
      if(ITextureRD_Ptr.isNULL())
        continue;

      // 貼圖座標的來源為第 0 號貼圖座標，所以 CVertexDDD3D.cpp 的 U,V 貼圖座標須先設定過
      //pDEVICE9->SetTextureStageState(TextureLevel, D3DTSS_TEXCOORDINDEX, 0); 

      if(IRenderDatagramDisposalCenterD3d_Arg->Exec((ITextureRD*)ITextureRD_Ptr,pDEVICE9) == false)
      {
        m_IStageDDD3D9_Ptr->SetStage(0);
        MutiTextureDD_D3D9_Clear(pDEVICE9);
        return false;
      }
/*
      doBlendMode(BlendMode, pDEVICE9, TextureLevel);

      if(TextureMatrix_cPtr.isNULL() == false)
      {
        C3DMatrix4x4 vTextureMatrix = *TextureMatrix_cPtr;
        vTextureMatrix.m_Vec2 = vTextureMatrix.m_Vec3;
        pDEVICE9->SetTransform(D3DTS_TEXTURE0, (D3DMATRIX *) &vTextureMatrix);
        pDEVICE9->SetTextureStageState(TextureLevel, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); // 讓 Texture Matrix 生效
      }
      else
        pDEVICE9->SetTextureStageState(TextureLevel, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); // 讓 Texture Matrix 失效
*/
    }

    m_IStageDDD3D9_Ptr->SetStage(0);
    return true;
  }

public:
  // Constructor
  CMutiTextureDD_D3D9()
    :cxxlObject(Spirit_Easy),
    m_IStageDDD3D9_Ptr(NULL,this),
    m_IPostDrawDDD3D9_Ptr(NULL,this)
  {
    ITextureRD_AttrBox_Num = 0;
  }

  // Destructor
  ~CMutiTextureDD_D3D9()
  {
  }
};

cxxlObject *cxxlFASTCALL New_CMutiTextureDD_D3D9()
{
  return new CMutiTextureDD_D3D9;
}

